<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>声笔飞码字根练习</title>
<script>
var root_map = [
    {
    	"a": [],
    },
    {
    	"b": ["八", "比", "贝", "貝", "白", "鼻", "卜", "⺊", "髟", "勹", "疒", "丷"],
    },
    {
    	"c": ["厂", "寸", "车", "車", "虫", "赤", "辰", "齿", "齒", "彳", "艹", "屮"],
    },
    {
    	"d": ["刀", "大", "歹", "斗", "鬥", "豆", "丶", "冫", " 氵", "癶"],
    },
    {
    	"e": [],
    },
    {
    	"f": ["方", "风", "風", "缶", "扌"],
    },
    {
    	"g": ["弓", "弓", "广", "戈", "瓜", "革", "骨", "鬼", "艮", "冖", "宀"],
    },
    {
    	"h": ["一", "户", "火", "禾", "黑", "虍"],
    },
    {
    	"i": [],
    },
    {
    	"j": ["几", "己", "巾", "斤", "见", "見", "臼", "角", "金", "钅", "釒", "纟", "糹"],
        
    },
    {
    	"k": ["口", "囗", "匚", "凵", "冂"],
        
    },
    {
    	"l": ["力", "立", "龙", "龍", "里", "鹿", "耒", "卤", "鹵", "刂", "忄", "辶", "廴", "灬"],
        
    },
    {
    	"m": ["马", "馬", "门", "門", "毛", "木", "皿", "目", "米", "麻", "麦", "麥", "母", "毋", "毌"],
    	
    },
    {
    	"n": ["牛", "女", "⺧", "鸟", "鳥", "礻", "衤", "廾", "止"],
    	
    },
    {
    	"o": [],
    },
    {
    	"p": ["皮", "片", "丿", "⺮", "彡"],
       
    },
    {
    	"q": ["气", "欠", "犬", "犭", "青", "其", "日", "曰", "攴"]
    },
    {
    	"r": ["人", "亻"]
    },
    {
    	"s": ["十", "山", "尸", "手", "水", "石", "矢", "身", "鼠", "示", "食", "饣", "飠", "殳", "豕", "丨", "厶"],
    },
    {
    	"t": ["田", "土", "士"],
        
    },
    {
    	"u": [],
       
    },
    {
    	"v" : ["二", "儿", "耳", "月", "羽", "鱼", "魚", "雨", "聿", "阝", "卩"],
        
    },
    {
    	"w": ["韦", "瓦", "王", "攵", "夂", "亠", "韋"],
        
    },
    {
    	"x": ["夕", "小", "心", "穴", "血", "覀", "辛", "彐", "糸", "⺌", "学头"],
        
    },
    {
    	"y": ["又", "用", "业", "页", "頁", "衣", "羊", "言", "讠", "音", "酉", "尢", "疋"],
        
    },
    {
    	"z": ["乙", "子", "舟", "自", "走", "豸", "足", "隹", "爪", "爫", "丬", "爿", "罒", "镸", "𧾷", "巛"],
        
    }
]



function main() {
    raw_area = document.getElementById("raw_area")
    user_input = document.getElementById("user_input")
    main_top = document.getElementById("maintop")
    speed_label = document.getElementById("speedlabel")
    total_label = document.getElementById("totallabel")
    speed_timer = null
    word_count = 0
    start_time = 0
    cur_input_max = 0
    cur_input_index = 0
    cur_tab = 0
    total_words = []
    total_index = 0

    display_release_note()
}

function display_release_note() {
    reset_timer()
    clear_tabs_background(999)
    clear_raw_area()
    enable_user_input(false)
    raw_area.style.fontSize = "16px"
    raw_area.style.fontHeight = "16px"
    var span = document.createElement("span")
    span.innerText = hereDoc(function () {/*
注意：本练习工具是在MoGu大佬的“徐码字根简码练习_2.5”修改而来的逸码字根练习修改，感谢MoGu大佬。

    */})
    raw_area.appendChild(span)
}

function display_help() {
    reset_timer()
    clear_tabs_background(0)
    clear_raw_area()
    enable_user_input(false)
    raw_area.style.fontSize = "16px"
    raw_area.style.fontHeight = "16px"
    var span = document.createElement("span")
    span.innerText = hereDoc(function () {/*
见 https://sbxlm.gitee.io/
    */})
    raw_area.appendChild(span)
}
//功能选择
function choose_root(val) {
    clear_tabs_background(val)
    enable_user_input(true)
    raw_area.style.fontSize = "45px"
    raw_area.style.fontHeight = "45px"
    user_input.removeAttribute("disabled")
    user_input.focus()
    total_index = 0
    word_count = 0
    cur_tab = val
    speed_label.innerText = "速度：0.00字/分"

    var all_words
    switch (val) {
        case 1:
            all_words = get_root_words('a', 'e')
            break
        case 2:
            all_words = get_root_words('f', 'i')
            break
        case 3:
            all_words = get_root_words('j', 'm')
            break
        case 4:
            all_words = get_root_words('n', 't')
            break
        case 5:
            all_words = get_root_words('u', 'z')
            break
        case 6:
            all_words = get_root_words('a', 'z')
            break
        default:
            alert("impossible")
    }

    var option = get_option()
    if (option == 0) {
        total_words = all_words
    } else if (option == 1) {
        var arr = gen_shuttled(all_words.length)
        for (var i = 0; i < arr.length; i++) {
            arr[i] = all_words[arr[i]]
        }
        total_words = arr
    } else {
        var arr = gen_randoms(get_setup_count("total_count"), 0, all_words.length)
        for (var i = 0; i < arr.length; i++) {
            arr[i] = all_words[arr[i]]
        }
        total_words = arr
    }

    next_words()
    key_hint()
    total_label.innerText = "\t进度：0/" + total_words.length + "字"
    
    reset_timer()
    //console.log("words: ", total_words.length)
}

function timeout() {
    speed_timer = setTimeout("timeout()", 500)
    var speed = 0.0
    var elapsed = new Date().getTime() - start_time
    if (word_count > 0 && elapsed > 0) {
        speed = word_count * 60 * 1000 / elapsed
        speed_label.innerText = "速度：" + speed.toFixed(2) + "字/分"
    }
}

function start_timer() {
    if (speed_timer == null) {
        start_time = new Date().getTime()
        timeout()
    }
}

function reset_timer() {
    if (speed_timer != null) {
        clearTimeout(speed_timer)
        speed_timer = null
    }
}

//字根展示
function get_root_words(begch, endch) {
    var words = new Array()
    var achar_code = 'a'.charCodeAt(0)
    if (endch == ';') {
	    var beg = begch.charCodeAt(0) - achar_code
	    var end = 'z'.charCodeAt(0) - achar_code + 1 + 1
    } else {
	    var beg = begch.charCodeAt(0) - achar_code
	    var end = endch.charCodeAt(0) - achar_code + 1
    }
    for (var i = beg; i < end; i++) {
        var objs = root_map[i]
        if (endch == ';' && i >= 26) {
        	var key = ';'
        } else {
        	var key = String.fromCharCode(achar_code + i)
        }
        var curobj = objs[key]
        for (var idx in curobj) {
            words.push({ "key": key, "code": curobj[idx]})
        }
    }
    return words
}

function next_words() {
    var last_count = total_words.length - total_index
    if (last_count <= 0) {
        return false
    }

    var word_need = Math.min(last_count, get_setup_count("one_time_count"))
    cur_input_max = word_need
    cur_input_index = 0
    clear_raw_area()

    var target_words = total_words.slice(total_index, total_index + word_need)
    for (idx in target_words) {
        var span = document.createElement("span")
        word = target_words[idx]
        span.innerText = word.code + " "
        span.setAttribute("key", word.key)
        span.id = "word" + idx
        span.style.color = "lightgrey"
        raw_area.appendChild(span)
    }
    total_index += word_need

    return true
}

function get_setup_count(id) {
    var node = document.getElementById(id)
    return parseInt(node.value)
}

function gen_shuttled(size) {
    var array = new Array()
    for (var i = 0; i < size; i++) {
        array.push(i)
    }
    for (var i = 0; i < size; i++) {
        var idx = Math.floor(Math.random() * size)
        var tmp = array[idx]
        array[idx] = array[i]
        array[i] = tmp
    }
    return array
}

function gen_randoms(size, beg, end) {
    var count = end - beg
    var array = new Array()
    for (var i = 0; i < size; i++) {
        array.push(Math.floor(Math.random() * count + beg))
    }
    return array
}

function get_option() {
    var radios = document.getElementsByName("radiobutton")
    for (var i = 0; i < radios.length; i++) {
        if (radios[i].checked) {
            return i
        }
    }
}

function is_hint_option_checked() {
    var checked = document.getElementsByName("key_hint_checkbox")[0].checked
    return checked
}

function key_hint() {
    if (user_input.getAttribute("disabled") != "true") {
        if (is_hint_option_checked()) {
            var word = document.getElementById("word" + cur_input_index)
            var key = word.getAttribute("key")
            user_input.setAttribute("placeholder", key)
        } else {
            user_input.setAttribute("placeholder", "")
        }
    }
}

function user_input_change() {
    if (cur_input_index >= cur_input_max)
        return

    var word = document.getElementById("word" + cur_input_index)
    var key = word.getAttribute("key")
    var val = user_input.value
    if (val[val.length-1] == " " || val[val.length-1] == ";" || val.length == key.length) {
        if (val.toLowerCase() == key) {
            start_timer()
            cur_input_index++
            word_count++
            total_label.innerText = "\t进度：" + word_count + "/" + total_words.length + "字"
            word.style.color = "black"
            user_input.setAttribute("placeholder", "")
        } else {
            word.style.color = "red"
            user_input.setAttribute("placeholder", key)
        }
        user_input.value = ""

        if (cur_input_index >= cur_input_max) {
            if (!next_words()) {
                user_input.setAttribute("disabled", "true")
                reset_timer()
            }
        }
        
        key_hint()
    }
    // console.log(word)
    // console.log(word.getAttribute("key"))
}

function hereDoc(f) {　
    return f.toString().replace(/^[^\/]+\/\*!?\s?/, '').replace(/\*\/[^\/]+$/, '');
}

function clear_tabs_background(activate_idx) {
    var tabs = document.getElementsByClassName("tab")
    for (var idx in tabs) {
        if (tabs[idx].style) {
            tabs[idx].style.backgroundColor = "#70abe6"
            tabs[idx].style.boxShadow="0 0 black"
        }
    }
    if (activate_idx != null) {
        var tab = document.getElementById("tab" + activate_idx)
        tab.style.backgroundColor = "white"
        tab.style.boxShadow="inset 0 0 7px 0px black"
    }
}

function msover(idx) {
    //console.log(idx)
    var tab = document.getElementById(idx);
    if (!/inset/.exec(tab.style.boxShadow)){
        tab.style.backgroundColor = "white"
        tab.style.boxShadow = "0 0 10px 0px black"
    } else {
        tab.style.backgroundColor = "white"
        tab.style.boxShadow="inset 0 0 7px 0px black"
    }
}

function msdown(idx) {
    var tab = document.getElementById(idx);
    if (!/inset/.exec(tab.style.boxShadow)){
        tab.style.backgroundColor = "white"
        tab.style.boxShadow = "inset 0 0 7px 0px black"
    }
}

function msout(idx) {
    var tab = document.getElementById(idx);
    if (!/inset/.exec(tab.style.boxShadow))
    {
        tab.style.backgroundColor = "#70abe6"
        tab.style.boxShadow="0 0 black"
    } else {
        tab.style.backgroundColor = "white"
        tab.style.boxShadow="inset 0 0 7px 0px black"
    }
}

function enable_user_input(val) {
    if (val) {
        user_input.style.display = "block"
        main_top.style.display = "block"

    } else {
        user_input.style.display = "none"
        main_top.style.display = "none"
    }
    user_input.value = ""
}

function clear_raw_area() {
    while (raw_area.hasChildNodes()) {
        raw_area.removeChild(raw_area.lastChild);
    }
}

</script>
<style>
html { font-family: '98WB-V', '98WB-U', '98WB-0', '98WB-1', '98WB-P1', '98WB-P2', '98WB-P3', '98WB-P15', 'sim-ch_n5100', 'Times New Roman', Times, serif; }

aside {
    text-align: center;
    width: 160px;
    height: 100%;
    background-color: #70abe6;
    position: absolute;
    top: 0;
    left: 0;
    font-size: 130%;
    cursor: default;
}

.textarea {
    width: 98%;
    min-height: 300px;
    padding: 8px;
    outline: 0;
    border: none;
    word-wrap: normal;
    overflow-y: visible;
    resize: none;

    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 0 16px rgba(82, 168, 236, 1);
}

.spinner, #user_input {
    padding: 5px;
    outline: 0;
    border: 2px solid #a0b3d6;

    border-color: rgba(82, 168, 236, 0.8);
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.1), 0 0 16px rgba(82, 168, 236, 0.6);
}

.tab:hover {
    background-color: white;
}

.tab {
    padding: 6px;
}

#content {
    padding-left: 170px;
    padding-top: 10px;
    padding-bottom: 10px;
    padding-right: 10px;
}

#maintop {
    padding-left: 170px;
    line-height: 35px;
}

#aside_title {
    font-size: 220%;
    padding: 20px;
}

#author {
    font-size: 100%;
    padding: 4px;
    padding-top: 15px;
    color: #fbfcff;
    text-shadow: 8px 7px 14px black;
    text-align: center;
    /* background-color: white; */
    box-shadow: inset 0 0 0px 0px black;
}

#user_input {
    margin-top: 20px;
    align-self: center;
    height: 80px;
    width: 90px;
    margin-left: 42%;
    align-content: center;
    font-size: 400%;
}
</style> 
</head>

<body onload="main()">
    <aside>
        <div id="aside_title">声笔飞码</div>
        <div class="tab" id="tab0" onmousedown="msdown('tab0')" onmouseout="msout('tab0')" onmouseover="msover('tab0')"  onclick="display_help()">快速入门</div>
        <div class="tab" id="tab1" onmousedown="msdown('tab1')" onmouseout="msout('tab1')" onmouseover="msover('tab1')"  onclick="choose_root(1)">'a-e'字根</div>
        <div class="tab" id="tab2" onmousedown="msdown('tab2')" onmouseout="msout('tab2')" onmouseover="msover('tab2')"  onclick="choose_root(2)">'f-i'字根</div>
        <div class="tab" id="tab3" onmousedown="msdown('tab3')" onmouseout="msout('tab3')" onmouseover="msover('tab3')"  onclick="choose_root(3)">'j-m'字根</div>
        <div class="tab" id="tab4" onmousedown="msdown('tab4')" onmouseout="msout('tab4')" onmouseover="msover('tab4')"  onclick="choose_root(4)">'n-t'字根</div>
        <div class="tab" id="tab5" onmousedown="msdown('tab5')" onmouseout="msout('tab5')" onmouseover="msover('tab5')"  onclick="choose_root(5)">'u-z'字根</div>
        <div class="tab" id="tab6" onmousedown="msdown('tab6')" onmouseout="msout('tab6')" onmouseover="msover('tab6')"  onclick="choose_root(6)">全部字根</div>
        <div class="tab" id="tab999" onmousedown="msdown('tab999')" onmouseout="msout('tab999')" onmouseover="msover('tab999')"  onclick="display_release_note()">更新历史</div>
        <div id="author">丹木 修改制作</div>
    </aside> 
    <div id="maintop">
        <br>
        <label>单次字根数：</label>
        <input id="one_time_count" class="spinner" type="number", min="10", max="500", value="30">
        <label>练习字根数：</label>
        <input id="total_count" class="spinner" type="number", min="10", max="500", value="120">
        </br>
        <input type="radio" name="radiobutton" onclick="choose_root(cur_tab)" checked="">顺序单次</input>
        <input type="radio" name="radiobutton" onclick="choose_root(cur_tab)">乱序单次</input>
        <input type="radio" name="radiobutton" onclick="choose_root(cur_tab)">乱序重复</input>
        <input type="checkbox" name="key_hint_checkbox" onclick="key_hint()">编码提示</input>
        <br>
        <label id="totallabel"></label>
        <label id="speedlabel"></label>
        </br>
    </div>
    <div id="content">
        <div class="textarea", id="raw_area"></div>
        <input id="user_input" oninput="user_input_change()">
    </div>
</body>
</html>